package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.constant.BsQiyeConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.BsQiye;
import com.ruoyi.system.domain.BsQiyeBusinessData;
import com.ruoyi.system.domain.dto.BsQiyeBusinessDataCountDTO;
import com.ruoyi.system.domain.ro.BsQiyeBusinessDataEditRO;
import com.ruoyi.system.domain.ro.BsQiyeBusinessDataRO;
import com.ruoyi.system.mapper.BsQiyeBusinessDataMapper;
import com.ruoyi.system.mapper.BsQiyeMapper;
import com.ruoyi.system.service.IBsQiyeBusinessDataService;
import io.github.classgraph.utils.Join;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 企业经营数据Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-23
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class BsQiyeBusinessDataServiceImpl implements IBsQiyeBusinessDataService {

    private final BsQiyeBusinessDataMapper baseMapper;
    private final BsQiyeMapper bsQiyeMapper;

//    @Scheduled(fixedRate = 1000)
//    @Scheduled(cron = "0 */1 * * * ?")
    @Scheduled(cron = "0 5 0 * * ? ")//凌晨00:05:00
    private void initTodayUnReportDataTime() {
        log.info("初始化所有审核通过商户-当天上报数据-start");
        List<BsQiye> qiYelist = bsQiyeMapper.selectList(new QueryWrapper<BsQiye>().lambda()
                .eq(BsQiye::getAuditStatus, BsQiyeConstants.AUDIT_STATUS.AUDIT_ALLOW));
        String today = DateUtil.today();
        List<BsQiyeBusinessData> todayList = baseMapper.selectList(new QueryWrapper<BsQiyeBusinessData>().lambda()
                .eq(BsQiyeBusinessData::getDate, today));
        List<Long> collect = todayList.stream().map(BsQiyeBusinessData::getQiyeId).collect(Collectors.toList());
        qiYelist.forEach(f -> {
            if (collect.isEmpty() || !collect.contains(f.getId())) {
                initTodayUnReportData(f.getId(), today);
            }
        });
        log.info("初始化所有审核通过商户-当天上报数据-end");
    }

    /**
     * 说明 : 商铺审核通过后 初始化当天上报数据-后续由每日定时任务完成
     * DateUtil.today()
     */
    public void initTodayUnReportData(Long qiYeId, String date) {
        try {
            BsQiyeBusinessDataRO build = BsQiyeBusinessDataRO.builder()
                    .qiyeId(qiYeId)
                    .date(date)
                    .build();
            build.setCreateBy(Constants.SYSTEM_USER);
            build.setUpdateBy(Constants.SYSTEM_USER);
            insertByBo(build);
        } catch (Exception e) {
            log.error("初始化当天上报数据异常", e);
        }
    }

    public void setUnReportNum(List<BsQiye> list) {
        List<Long> ids = list.stream().map(BsQiye::getId).collect(Collectors.toList());
        Map<Long, Integer> map = getUnReportNum(ids);
        System.out.println("map = " + JSONObject.toJSONString(map));
        list.forEach(f -> {
            if (map.get(f.getId()) != null) {
                f.setUnReportNum(map.get(f.getId()));
            } else {
                f.setUnReportNum(0);
            }
        });
    }

    private Map<Long, Integer> getUnReportNum(List<Long> ids) {
        if (ids.isEmpty()) {
            return new HashMap<>();
        }
        String join = Join.join(",", ids);
        List<BsQiyeBusinessDataCountDTO> list = baseMapper.getUnReportNum(join, BsQiyeConstants.REPORT_TYPE.UN_REPORT);
        return list.stream().collect(Collectors.toMap(BsQiyeBusinessDataCountDTO::getQiYeId, BsQiyeBusinessDataCountDTO::getCountNum));
    }

    /**
     * 查询企业经营数据
     */
    @Override
    public BsQiyeBusinessData queryById(Long id) {
        return baseMapper.selectById(id);
    }

    /**
     * 查询企业经营数据列表
     */
    @Override
    public List<BsQiyeBusinessData> queryList(BsQiyeBusinessDataRO bo) {
        LambdaQueryWrapper<BsQiyeBusinessData> lqw = buildQueryWrapper(bo);
        return baseMapper.selectList(lqw);
    }

    private LambdaQueryWrapper<BsQiyeBusinessData> buildQueryWrapper(BsQiyeBusinessDataRO bo) {
        LambdaQueryWrapper<BsQiyeBusinessData> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getQiyeId() != null, BsQiyeBusinessData::getQiyeId, bo.getQiyeId());
        lqw.eq(StringUtils.isNotBlank(bo.getDate()), BsQiyeBusinessData::getDate, bo.getDate());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), BsQiyeBusinessData::getType, bo.getType());
        lqw.eq(bo.getBusinessAmount() != null, BsQiyeBusinessData::getBusinessAmount, bo.getBusinessAmount());
        lqw.eq(bo.getBusinessPersonTime() != null, BsQiyeBusinessData::getBusinessPersonTime, bo.getBusinessPersonTime());
        lqw.orderByDesc(BsQiyeBusinessData::getCreateTime);
        return lqw;
    }

    /**
     * 新增企业经营数据
     */
    @Override
    public Boolean insertByBo(BsQiyeBusinessDataRO ro) {
        BsQiyeBusinessData add = BeanUtil.toBean(ro, BsQiyeBusinessData.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            ro.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改企业经营数据
     */
    @Override
    public Boolean updateByBo(BsQiyeBusinessDataEditRO ro) {
        BsQiyeBusinessData update = BeanUtil.toBean(ro, BsQiyeBusinessData.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BsQiyeBusinessData entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除企业经营数据
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
